
#include "pulse_msp_init.h"

TIM_HandleTypeDef Tim2Handle;
__IO unsigned int capture_Buf[3] = {0};
__IO unsigned char capture_Cnt = 0;
__IO unsigned char overTimes = 0;

void pulse_gpio_init()
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin   = GPIO_PIN_2;
    GPIO_InitStruct.Mode  = GPIO_MODE_AF_INPUT/*GPIO_MODE_AF_PP*/;
    GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
}

void pulse_timer_init()
{
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_IC_InitTypeDef sConfigIC = {0};

    /* Peripheral clock enable */
    __HAL_RCC_TIM2_CLK_ENABLE();

    /* USER CODE BEGIN TIM2_Init 1 */
    Tim2Handle.Instance = TIM2;
    Tim2Handle.Init.Prescaler = 72 - 1;
    Tim2Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    Tim2Handle.Init.Period = 0xFFFF;
    Tim2Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    Tim2Handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&Tim2Handle) != HAL_OK)
    {
        Error_Handler();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&Tim2Handle, &sClockSourceConfig) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_TIM_IC_Init(&Tim2Handle) != HAL_OK)
    {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&Tim2Handle, &sMasterConfig) != HAL_OK)
    {
        Error_Handler();
    }
    sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
    sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
    sConfigIC.ICFilter = 0;
    if (HAL_TIM_IC_ConfigChannel(&Tim2Handle, &sConfigIC, TIM_CHANNEL_3) != HAL_OK)
    {
        Error_Handler();
    }
    /* USER CODE END TIM2_Init 1 */

    /* TIM2 interrupt Init */
    HAL_NVIC_SetPriority(TIM2_IRQn, 1, 2);
    HAL_NVIC_EnableIRQ(TIM2_IRQn);

    HAL_TIM_Base_Start_IT(&Tim2Handle);
    /* 启动定时器通道输入捕获并开启中断 */
    HAL_TIM_IC_Start_IT(&Tim2Handle, TIM_CHANNEL_3);  
}

void pulse_msp_init()
{
	pulse_gpio_init();
	pulse_timer_init();
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef * htim)
{
    if ((htim->Instance == TIM2) && (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)) {
        if (capture_Cnt == 0) {
            // 获取当前的捕获值
            capture_Buf[0] = HAL_TIM_ReadCapturedValue(&Tim2Handle, TIM_CHANNEL_3);
            capture_Cnt = 1;

            TIM_RESET_CAPTUREPOLARITY(&Tim2Handle, TIM_CHANNEL_3);
            // 设置为下降沿捕获
            __HAL_TIM_SET_CAPTUREPOLARITY(&Tim2Handle, TIM_CHANNEL_3, TIM_INPUTCHANNELPOLARITY_RISING/*TIM_ICPOLARITY_FALLING*/);
            HAL_TIM_IC_Start_IT(&Tim2Handle, TIM_CHANNEL_3);
        } else if (capture_Cnt == 1) {
            // 获取当前的捕获值
            capture_Buf[1] = HAL_TIM_ReadCapturedValue(&Tim2Handle, TIM_CHANNEL_3);
            capture_Cnt = 2;

            __HAL_TIM_SET_COUNTER(&Tim2Handle, 0);
            // 停止捕获，或者使用 __HAL_TIM_DISABLE(&Tim2Handle) 关闭定时器
            HAL_TIM_IC_Stop_IT(&Tim2Handle, TIM_CHANNEL_3);
        }
    }
}

// TIM 溢出中断函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim)
{
    if (htim->Instance == TIM2) {
        if (capture_Cnt == 1)
            overTimes++;
        else
            overTimes = 0;
    }
}

void TIM2_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&Tim2Handle);
}

static void Error_Handler()
{
    while (1)
    {

    }
}

/*******************************************
 *          PUL MSP TEST
 ******************************************/

void pulse_test_gpio_init()
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin   = GPIO_PIN_2; // PUL
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void pulse_test_gpio()
{
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_Delay(20);

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
    HAL_Delay(20);
}
